/*
 * Copyright 2010 Biz-e (info@biz-e.nl)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package nl.biz_e.acl.client.data;

import java.util.List;

import nl.biz_e.acl.client.ContextService;
import nl.biz_e.acl.client.ContextServiceAsync;
import nl.biz_e.acl.shared.model.Context;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;

/**
 * Controller for {@link Context}s.
 * 
 * @author Joost A. Bloemsma
 * 
 */
public class ContextController extends AbstractController {
	private Context ctx;
	private Context parentCtx = null;
	private final ContextServiceAsync ctxService;
	
	/**
	 * Constructs a new ContextController instance
	 */
	public ContextController() {
		ctxService = GWT.create(ContextService.class);
	}
	
	/**
	 * @return the ctx
	 */
	public Context getCtx() {
		return ctx;
	}
	
	/**
	 * Persists the current {@link Context}
	 */
	public void save() {
		ctxService.saveContext(getCtx(), new AsyncCallback<Void>() {
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Failure");
			}
			
			@Override
			public void onSuccess(Void result) {
				Window.alert("Success");
			}
		});
	}
	
	/**
	 * Returns the parent context of the current {@link Context}
	 * 
	 * @return the parent {@link Context}
	 */
	public Context getParentContext() {
		if (ctx == null)
			return null;
		if (parentCtx == null) {
			ctxService.getParentContext(ctx, new AsyncCallback<Context>() {
				private ControllerEvent event = new ControllerEvent();
				
				@Override
				public void onSuccess(Context result) {
					parentCtx = result;
					ContextController.this.notify(event);
				}
				
				@Override
				public void onFailure(Throwable caught) {
					// TODO Auto-generated method stub
					
				}
			});
			return null;
		} else {
			return parentCtx;
		}
	}
	
	/**
	 * Fills the passed {@link ContextListHolder} with all existing contexts
	 * 
	 * @param holder
	 */
	public void fillContexts(final ContextListHolder holder) {
		ctxService.getAllContexts(new AsyncCallback<List<Context>>() {
			
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("Failed getting contexts");
			}
			
			@Override
			public void onSuccess(List<Context> result) {
				holder.setExistingContexts(result);
			}
		});
	}
	
	/**
	 * @param ctx
	 *        the ctx to set
	 */
	public void setCtx(Context ctx) {
		this.ctx = ctx;
	}
	
	/**
	 * Checks if the passed context id can be a parent for the current
	 * {@link Context}
	 * 
	 * @param ctxId
	 * @return true or false
	 */
	public boolean isValidParentId(String ctxId) {
		return !(ctxId.equals(this.ctx.getContextId()));
	}
	
	/**
	 * Can hold a list of {@link Context}s
	 * 
	 * @author Joost A. Bloemsma
	 * 
	 */
	public interface ContextListHolder {
		/**
		 * Sets the list.
		 * Is called from
		 * {@link ContextController#fillContexts(ContextListHolder)}
		 * 
		 * @param list
		 */
		public void setExistingContexts(Iterable<Context> list);
	}
}
